package com.yhn.init.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yhn.init.common.DeleteRequest;
import com.yhn.init.common.ErrorCode;
import com.yhn.init.constant.FileConstant;
import com.yhn.init.exception.BusinessException;
import com.yhn.init.exception.ThrowUtils;
import com.yhn.init.mapper.InstallationDetailsMapper;
import com.yhn.init.model.dto.installationDetails.AfterInstallationRequest;
import com.yhn.init.model.dto.installationDetails.InstallationDetailsQueryRequest;
import com.yhn.init.model.dto.installationDetails.InstallationDetailsUpdateRequest;
import com.yhn.init.model.entity.InstallationDetails;
import com.yhn.init.model.vo.InstallationDetailsVO;
import com.yhn.init.service.FileService;
import com.yhn.init.service.InstallationDetailsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yhnyhn123
 */

@Slf4j
@Service("installationDetailsService")
public class InstallationDetailsServiceImpl extends ServiceImpl<InstallationDetailsMapper, InstallationDetails> implements InstallationDetailsService {

    @Resource
    private FileService fileService;

    @Override
    public Page<InstallationDetailsVO> queryPage(InstallationDetailsQueryRequest installationDetailsQueryRequest) {
        if (installationDetailsQueryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long current = installationDetailsQueryRequest.getCurrent();
        long size = installationDetailsQueryRequest.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
        Page<InstallationDetails> installationDetailsPage = this.page(new Page<>(current, size),
                this.getQueryWrapper(installationDetailsQueryRequest));
        Page<InstallationDetailsVO> installationDetailsVOPage = new Page<>(current, size, installationDetailsPage.getTotal());
        List<InstallationDetailsVO> installationDetailsVO = this.getInstallationDetailsVO(installationDetailsPage.getRecords());
        installationDetailsVOPage.setRecords(installationDetailsVO);
        return installationDetailsVOPage;
    }


    @Override
    public QueryWrapper<InstallationDetails> getQueryWrapper(InstallationDetailsQueryRequest installationDetailsQueryRequest) {
        QueryWrapper<InstallationDetails> queryWrapper = new QueryWrapper<>();
        // 如果请求对象为空，直接返回一个空的查询包装器
        if (installationDetailsQueryRequest == null) {
            return queryWrapper;
        }
        // 从请求对象中获取各项查询条件
        Long id = installationDetailsQueryRequest.getId();
        queryWrapper.eq(id != null && id > 0, "id", id);
        return queryWrapper;
    }

    /**
     * 获取脱敏对象集合
     *
     * @param installationDetailsList 查询请求
     * @return 脱敏对象集合
     */
    @Override
    public List<InstallationDetailsVO> getInstallationDetailsVO(List<InstallationDetails> installationDetailsList) {
        if (CollUtil.isEmpty(installationDetailsList)) {
            return new ArrayList<>();
        }
        return installationDetailsList.stream().map(this::getInstallationDetailsVO).collect(Collectors.toList());
    }


    /**
     * 将对象转化为脱敏对象
     *
     * @param installationDetails 原对象
     * @return 脱敏对象
     */
    @Override
    public InstallationDetailsVO getInstallationDetailsVO(InstallationDetails installationDetails) {
        if (installationDetails == null) {
            return null;
        }
        InstallationDetailsVO installationDetailsVO = new InstallationDetailsVO();
        BeanUtils.copyProperties(installationDetails, installationDetailsVO);
        return installationDetailsVO;
    }

    /**
     * 根据ID获取信息
     *
     * @param id id
     * @return 实体信息
     */
    @Override
    public InstallationDetailsVO getInfoById(Long id) {
        InstallationDetails installationDetails = this.getById(id);
        if (installationDetails == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "没有对应的信息");
        }
        return getInstallationDetailsVO(installationDetails);
    }

    /**
     * 保存信息
     *
     * @param installationDetailsAddRequest 添加请求
     * @return 新生成的ID
     */
    @Override
    @Transactional
    public Long saveInstallationDetails(AfterInstallationRequest installationDetailsAddRequest) {
        if (installationDetailsAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        InstallationDetails installationDetails = new InstallationDetails();
        BeanUtils.copyProperties(installationDetailsAddRequest, installationDetails);
        boolean result = this.save(installationDetails);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return installationDetails.getId();
    }


    /**
     * 修改信息
     *
     * @param installationDetailsUpdateRequest 修改请求
     * @return 是否修改成功
     */
    @Override
    @Transactional
    public Boolean updateInstallationDetails(InstallationDetailsUpdateRequest installationDetailsUpdateRequest) {
        if (installationDetailsUpdateRequest == null || installationDetailsUpdateRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        InstallationDetails installationDetails = new InstallationDetails();
        BeanUtils.copyProperties(installationDetailsUpdateRequest, installationDetails);
        long id = installationDetailsUpdateRequest.getId();
        // 判断是否存在
        InstallationDetails oldInstallationDetails = this.getById(id);
        ThrowUtils.throwIf(oldInstallationDetails == null, ErrorCode.NOT_FOUND_ERROR);
        boolean result = this.updateById(installationDetails);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return result;
    }

    /**
     * 删除信息
     *
     * @param deleteRequest 删除请求
     * @return 是否修改成功
     */
    @Override
    public Boolean deleteById(DeleteRequest deleteRequest) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long id = deleteRequest.getId();
        // 判断是否存在
        boolean b = this.removeById(id);
        ThrowUtils.throwIf(!b, ErrorCode.NOT_FOUND_ERROR);
        return b;
    }


    /**
     * 批量删除
     *
     * @param ids 批量删除的IDS
     * @return 是否删除成功
     */
    @Override
    @Transactional
    public Boolean deleteBatchByIds(Long[] ids) {
        if (ids == null || ids.length == 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean b = this.removeByIds(Arrays.asList(ids));
        ThrowUtils.throwIf(!b, ErrorCode.NOT_FOUND_ERROR);
        return b;
    }

    /**
     * 安装师完成安装后填写信息
     *
     * @param productImg               产品信息
     * @param customerPhoto            客户合照
     * @param customerSignature        客户电子签字
     * @param afterInstallationRequest 请求
     * @return 安装信息
     */
    @Override
    @Transactional
    public InstallationDetailsVO afterInstallation(MultipartFile productImg,
                                                   MultipartFile customerPhoto,
                                                   MultipartFile customerSignature,
                                                   AfterInstallationRequest afterInstallationRequest) {
        if (productImg == null || customerPhoto == null || customerSignature == null || afterInstallationRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数不能为空");
        }
        String productPath = fileService.uploadImage(productImg, FileConstant.FILE_UPLOAD_PATH_IMG);
        String customerPhotoPath = fileService.uploadImage(customerPhoto, FileConstant.FILE_UPLOAD_PATH_IMG);
        String originalFilename = customerSignature.getOriginalFilename();
        String suffix = FileUtil.getSuffix(originalFilename);
        String customerSignaturePath;
        //如果用户电子签字文件类型是PDF
        if (FileConstant.VALID_PDF_SUFFIX.contains(suffix)) {
            customerSignaturePath = fileService.uploadPdf(customerSignature, FileConstant.FILE_UPLOAD_PATH_PDF);
        } else {//反之则是word,否则异常
            customerSignaturePath = fileService.uploadWord(customerSignature, FileConstant.FILE_UPLOAD_PATH_DOCX);
        }
        InstallationDetails installationDetails = new InstallationDetails();
        BeanUtils.copyProperties(afterInstallationRequest, installationDetails);
        installationDetails.setPhotoUrl(productPath);
        installationDetails.setCustomerPhoto(customerPhotoPath);
        installationDetails.setCustomerSignature(customerSignaturePath);
        ThrowUtils.throwIf(!this.save(installationDetails), ErrorCode.DATABASE_ERROR);
        return getInstallationDetailsVO(installationDetails);
    }
}
